<template>
  <el-dialog :title="title" :visible.sync="dialogVisible" width="904px">
    <div class="dialog-box">
      <div class="player-info-box">
        <div class="player-form">
          <div class="title">角色信息</div>
          <el-form ref="playerForm" :model="playerForm" :rules="playerRules">
            <el-form-item label="角色名称" prop="name" required>
              <el-input
                v-model="playerForm.name"
                placeholder="请输入角色名称"
              />
            </el-form-item>
            <el-form-item label="角色ID" prop="id" required>
              <el-input v-model="playerForm.id" placeholder="请输入角色ID" />
            </el-form-item>
            <el-form-item label="角色描述" prop="desc">
              <el-input
                v-model="playerForm.desc"
                placeholder="请输入角色描述"
              />
            </el-form-item>
          </el-form>
        </div>

        <div class="player-root">
          <div class="title">功能权限</div>
          <div class="range">
            <div class="range-name">数据可见范围：</div>
            <div class="range-group">
              <el-radio-group v-model="visibleRange">
                <el-radio :label="0"> 组织内数据 </el-radio>
                <el-radio :label="1"> 部门内数据 </el-radio>
                <el-radio :label="2"> 与我有关的数据 </el-radio>
              </el-radio-group>
            </div>
          </div>
          <div class="range-root">
            <div class="range-page-checkbox">
              <div class="root-title">
                <el-checkbox
                  v-model="checkPageAll"
                  :indeterminate="isPageCheckAll"
                  @change="handlePageCheckAllChange"
                >
                  可见页面
                </el-checkbox>
              </div>

              <el-checkbox-group
                v-model="checkedPages"
                @change="handlePageCheckChange"
              >
                <el-checkbox
                  v-for="item in pageData"
                  :key="item.id"
                  :label="item.id"
                >
                  {{ item.label }}
                </el-checkbox>
              </el-checkbox-group>
            </div>
            <div class="range-handle-checkbox">
              <div class="root-title">功能权限</div>
              <div
                v-for="(_, index) in pageData"
                :key="pageData[index].id"
                class="handle-box"
              >
                <el-checkbox
                  v-model="isHandleCheckAll[index].isCheckAll"
                  :indeterminate="isHandleCheckAll[index].isIndeterminate"
                  :disabled="!pageData[index].ischecked"
                  @change="(val) => handleCheckAllChange(val, index)"
                >
                  全选
                </el-checkbox>
                <el-checkbox-group
                  v-model="isHandleCheckAll[index].checkedHandle"
                  @change="(handles) => handleCheckChange(handles, index)"
                >
                  <el-checkbox
                    v-for="item in handleData"
                    :key="item.key"
                    :label="item.key"
                    :disabled="!pageData[index].ischecked"
                  >
                    {{ item.label }}
                  </el-checkbox>
                </el-checkbox-group>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <span slot="footer" class="dialog-footer">
      <el-button @click="handleClick('cancel')">取 消</el-button>
      <el-button type="primary" @click="handleClick('confirm')"
        >确 定</el-button
      >
    </span>
  </el-dialog>
</template>
<script>
import {pageData, handleData} from '../mock/mockdata.js';
export default {
  props: {
    title: {
      // 弹窗标题
      type: String,
      default: '因为你没有传标题所以我是标题',
    },
    type: {
      // 弹窗类型，因为新建和修改的页面大体相同，所以用一个样式写
      type: String,
      default: 'add',
    },
    form: {
      // 角色信息数据，如果是type为add，则是{}
      type: Object,
      default: () => {
        return {};
      },
    },
  },
  data() {
    return {
      dialogVisible: false, // 控制弹窗是否显示
      playerForm: {}, // 角色信息
      playerRules: {
        name: [{required: true, message: '请输入角色名称'}],
        id: [{required: true, message: '请输入角色ID'}],
      }, // 表单的验证信息
      playerRoot: {}, // 角色权限信息
      visibleRange: 0, // 数据可见范围单选框的label值
      pageData, // 页面数据，是一个数组，里面的项可以是复杂类型
      pageDataKey: [], // 页面数据选中值，一般是数组项中的key/id，能够指定唯一的页面。该值根据pageData确定
      checkedPages: [], // 选中的所有页面，label值
      isPageCheckAll: false, // 页面数据的部分选中效果，为true时显示-，为false时不显示
      checkPageAll: false, // 页面数据的选中效果，为true时表示全选，显示√，为false时不显示
      handleData,
      handleDataKey: [0, 1, 2, 3], // 0:新增，1：修改，2：删除，3：查看
      isHandleCheckAll: [
        /* {
          id: 111, // 页面id，或者其他什么，反正能跟页面数据对应就行
          isIndeterminate: true, // 页面权限的部分选中效果
          isCheckAll:false,// 页面权限数据的选中效果，为true时表示全选，显示√，为false时不显示
          checkedHandle: [], // 选中的所有操作，label值
        } */
      ],
      check: false,
    };
  },
  created() {
    this.initData();
  },
  methods: {
    initData() {
      if (this.type === 'add') {
        this.playerForm = {};
      } else {
        this.playerForm = this.$utils.easyDeepClone(this.form);
      }
      // 处理接口获取的页面数据，转换成mockData里pageData的数据格式，现在先是mock的数据
      // 根据pageData提取pageDataKey
      this.pageDataKey = this.getProperty(this.pageData, 'id');
      // 根据pageData提取checkedPages
      this.checkedPages = this.getCheckedPages(this.pageData);
      // 根据pageData生成isHandleCheckAll
      this.isHandleCheckAll = this.getIsHandleCheckAll(this.pageData);
      /* console.table(this.isHandleCheckAll); */
    },
    handleClick(type) {
      if (type === 'confirm') {
        // 验证表单
        if (!this.checkForm()) {
          this.$message.error('请完善角色信息');
          return;
        }
        // 意味着要新增/修改角色，需要提交数据
        this.getNewPageData();
        // 调用接口。。。
      } else {
        // 放弃更改
      }
      this.$emit(type, 'mod');
      this.dialogVisible = false;
    },
    checkForm() {
      let flag = false;
      this.$refs.playerForm.validate((valid) => {
        if (valid) {
          flag = true;
        } else {
          flag = false;
        }
      });
      return flag;
    },
    handlePageCheckAllChange(val) {
      // 当选择“可见页面”前面的多选框时，触发这个函数
      // 如果选中了，就让pages（选中的所有页面）的值为pageData（当前可操作的所有页面）
      this.checkedPages = val ? this.pageDataKey : [];
      this.isPageCheckAll = false;
    },
    handlePageCheckChange(pages) {
      // 当选择页面名称前面的多选框时，触发这个函数
      // 检查一下是否选择了全部页面
      this.checkPageAll = pages.length === this.pageData.length;
      this.isPageCheckAll =
        pages.length > 0 && pages.length < this.pageData.length;
      // 将所有页面的ischecked改为false
      this.pageData.forEach((_, index) => {
        this.$set(this.pageData[index], 'ischecked', false);
      });
      // 再将被选择的页面的ischecked属性改为true
      pages.forEach((i) => {
        const index = this.pageData.findIndex((item) => {
          return item.id === i;
        });
        this.$set(this.pageData[index], 'ischecked', true);
      });
    },
    handleCheckAllChange(val, index) {
      // 全选框被点击时触发
      // 如果选中了 就要勾选全部的操作框
      const checkedHandle = val ? this.handleDataKey : [];
      const isIndeterminate = false;
      this.$set(this.isHandleCheckAll[index], 'checkedHandle', checkedHandle);
      this.$set(
        this.isHandleCheckAll[index],
        'isIndeterminate',
        isIndeterminate
      );
    },
    handleCheckChange(handles, index) {
      // 当选择handle（新增修改删除查看）前面的多选框时，触发这个函数
      const isCheckAll = handles.length === this.handleData.length;
      const isIndeterminate =
        handles.length > 0 && handles.length < this.handleData.length;
      this.$set(this.isHandleCheckAll[index], 'isCheckAll', isCheckAll);
      this.$set(
        this.isHandleCheckAll[index],
        'isIndeterminate',
        isIndeterminate
      );
    },
    // 将数组对象中的某个key的值提取出来变成数组
    getProperty(arr, key) {
      const resultArr = [];
      arr.forEach((item) => {
        const temp = item[key] ? item[key] : undefined;
        resultArr.push(temp);
      });
      return resultArr;
    },
    getIsHandleCheckAll(data) {
      const result = [];
      data.forEach((item) => {
        const temp = {};
        let length = 0;
        temp.id = item.id;
        temp.checkedHandle = this.$utils.easyDeepClone(item.handleChecked);
        length = temp.checkedHandle.length;
        temp.isIndeterminate = !!(
          length > 0 && length < this.handleDataKey.length
        );
        (temp.isCheckAll = length === this.handleDataKey.length),
        result.push(temp);
      });
      return result;
    },
    getCheckedPages(data) {
      const result = [];
      data.forEach((item) => {
        if (item.ischecked) {
          result.push(item.id);
        }
      });
      if (result.length > 0) this.isPageCheckAll = true;
      return result;
    },
    getNewPageData() {
      console.log('a');
      // 获取当前最新的页面权限数据
      // 主要是更新pageData的handleChecked
      // 如果pageData的某一项ischecked属性为true，则将isHandleCheckAll中，对应项的checkedHandle赋值给handleChecked，为false是[]
      this.pageData.forEach((item, index) => {
        if (item.ischecked) {
          item.handleChecked = this.$utils.easyDeepClone(
            this.isHandleCheckAll[index].checkedHandle
          );
        } else {
          item.handleChecked = [];
        }
      });
      // 然后可以将pageData处理成接口数据的格式
    },
  },
};
</script>
<style lang="scss" scoped>
/deep/.el-dialog {
  .el-dialog__header {
    padding: 14px 24px;
    border-bottom: 1px solid #dadfe6;
    .el-dialog__title {
      font-weight: bold;
    }
  }
  .el-dialog__body {
    padding: 20px;
    .dialog-box {
      .player-info-box {
        .title {
          position: relative;
          margin-left: 16px;
          font-size: 16px;
          height: 18px;
          line-height: 18px;
          font-weight: bold;
          &::before {
            position: absolute;
            top: 2px;
            left: -16px;
            content: "";
            width: 4px;
            height: 14px;
            line-height: 18px;
            border-radius: 2px;
            background-color: #1970ff;
          }
        }
        .player-form {
          margin-bottom: 23px;
          .el-form {
            display: flex;
            flex-wrap: wrap;
            justify-content: space-between;
            .el-form-item {
              width: 100%;
              margin-bottom: 5px;
              .el-form-item__content {
                line-height: 32px;
                .el-input {
                  .el-input__inner {
                    height: 32px;
                    line-height: 32px;
                  }
                }
              }
              &.is-required {
                width: 45%;
              }
            }
          }
        }
        .player-root {
          .range {
            margin-top: 20px;
            display: flex;
            justify-content: space-between;
            height: 40px;
            box-sizing: border-box;
            padding: 0 24px;
            background: rgba(230, 233, 237, 0.3);
            border-radius: 2px;
            line-height: 40px;
            .range-name {
              font-size: 14px;
              font-weight: bold;
              color: #333333;
            }
            .range-group {
              .el-radio-group {
                .el-radio {
                  .el-radio__input {
                    &.is-checked {
                      .el-radio__inner {
                        background: transparent;
                        &::after {
                          background-color: #409eff;
                          transform: translate(-50%, -50%) scale(1.5);
                        }
                      }
                    }
                  }
                  .el-radio__label {
                    color: #666666;
                  }
                }
              }
            }
          }
          .range-root {
            height: 200px;
            overflow-y: scroll;
            display: flex;
            .el-checkbox__input.is-checked + .el-checkbox__label {
              color: #606266;
            }
            .root-title {
              height: 38px;
              line-height: 38px;
              font-weight: bold;
              padding-left: 20px;
              .el-checkbox {
                .el-checkbox__label {
                  font-weight: bold;
                }
              }
            }
            .range-page-checkbox {
              .el-checkbox-group {
                display: flex;
                flex-direction: column;
                .el-checkbox {
                  height: 38px;
                  line-height: 38px;
                  border-bottom: 1px solid #dadfe6;
                  padding-left: 20px;
                  margin-right: 0;
                  &:first-child {
                    border-top: 1px solid #dadfe6;
                  }
                  &:last-child {
                    border-bottom: none;
                  }
                }
              }
            }
            .range-handle-checkbox {
              width: 100%;
              .root-title {
                margin-left: 100px;
              }
              .handle-box {
                display: flex;
                height: 38px;
                line-height: 38px;
                border-bottom: 1px solid #dadfe6;
                padding-left: 100px;
                &:nth-child(2) {
                  border-top: 1px solid #dadfe6;
                }
                &:last-child {
                  border-bottom: none;
                }
                .el-checkbox {
                  margin-right: 50px;
                }
              }
            }
          }
        }
      }
    }
  }
  .el-dialog__footer {
    border-top: 1px solid #dadfe6;
    text-align: center;
  }
}
</style>